home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / SLIP.C < prev    next >
Text File  |  1993-08-22  |  3KB  |  137 lines

  1. /* Send and receive IP datagrams on serial lines. Compatible with SLIP
  2.  * under Berkeley Unix.
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "config.h"
  7. #include "mbuf.h"
  8. #include "iface.h"
  9. #include "config.h"
  10. #include "internet.h"
  11. #include "ip.h"
  12. #include "ax25.h"
  13. #include "slip.h"
  14. #include "asy.h"
  15. #include "trace.h"
  16.  
  17. /* Slip level control structure */
  18. struct slip Slip[ASY_MAX];
  19.  
  20. /* Send routine for point-to-point slip
  21.  * This is a trivial function since there is no slip link-level header
  22.  */
  23. int
  24. slip_send(
  25. struct mbuf *bp,        /* Buffer to send */
  26. struct iface *iface,    /* Pointer to interface control block */
  27. int32 gateway,            /* Ignored (SLIP is point-to-point) */
  28. int prec,int del,int tput,int rel)
  29. {
  30.     if(iface == NULLIF) {
  31.         free_p(bp);
  32.         return -1;
  33.     }
  34.     return (*iface->raw)(iface,bp);
  35. }
  36.  
  37. /* Send a raw slip frame -- also trivial */
  38. int
  39. slip_raw(struct iface *iface,struct mbuf *bp)
  40. {
  41.     int c;
  42.     char *cp;
  43.     struct mbuf *lbp;
  44.  
  45.     dump(iface,IF_TRACE_OUT,Slip[iface->xdev].type,bp);
  46.  
  47.     /* Allocate output mbuf that's twice as long as the packet.
  48.      * This is a worst-case guess (consider a packet full of FR_ENDs!)
  49.      */
  50.     lbp = alloc_mbuf((2 * len_p(bp)) + 2);
  51.     cp = lbp->data;
  52.  
  53.     /* Flush out any line garbage */
  54.     *cp++ = FR_END;
  55.  
  56.     /* Copy input to output, escaping special characters */
  57.     while((c = PULLCHAR(&bp)) != -1){
  58.         switch(c){
  59.         case FR_ESC:
  60.             *cp++ = FR_ESC;
  61.             *cp++ = T_FR_ESC;
  62.             break;
  63.         case FR_END:
  64.             *cp++ = FR_ESC;
  65.             *cp++ = T_FR_END;
  66.             break;
  67.         default:
  68.             *cp++ = c;
  69.         }
  70.     }
  71.     *cp++ = FR_END;
  72.     lbp->cnt = cp - lbp->data;
  73.  
  74.     return Slip[iface->xdev].send(iface->dev,lbp);
  75. }
  76.  
  77. /* Process SLIP line input */
  78. void
  79. asy_rx(int dev,void *p1,void *p2)
  80. {
  81.     int c;
  82.     struct phdr phdr;
  83.     struct slip *sp = &Slip[dev];
  84.  
  85.     for(;;) {
  86.         if((c = sp->get(sp->iface->dev)) == FR_ESC) {
  87.             sp->escaped |= SLIP_FLAG;
  88.         } else if(c == FR_END) {
  89.             struct mbuf *bp = sp->rbp;
  90.             sp->rbp = NULLBUF;
  91.             sp->rcnt = 0;
  92.             if(bp != NULLBUF) {
  93.                 struct mbuf *nbp = pushdown(bp,sizeof(struct phdr));
  94.                 phdr.iface = sp->iface;
  95.                 phdr.type = sp->type;
  96.                 memcpy(&nbp->data[0],(char *)&phdr,sizeof(struct phdr));
  97.                 enqueue(&Hopper,nbp);
  98.             }
  99.         } else {
  100.             if(sp->escaped & SLIP_FLAG) {
  101.                 /* Translate 2-char escape sequence back to original char */
  102.                 sp->escaped &= ~SLIP_FLAG;
  103.                 switch(c) {
  104.                 case T_FR_ESC:
  105.                     c = FR_ESC;
  106.                     break;
  107.                 case T_FR_END:
  108.                     c = FR_END;
  109.                     break;
  110.                 default:
  111.                     sp->errors++;
  112.                     break;
  113.                 }
  114.             }
  115.             /* We reach here with a character for the buffer;
  116.              * make sure there's space for it
  117.              */
  118.             if(sp->rbp == NULLBUF) {
  119.                 /* Allocate first mbuf for new packet */
  120.                 sp->rbp1 = sp->rbp = alloc_mbuf(sp->iface->mtu);
  121.                 sp->rcp = sp->rbp->data;
  122.             } else if(sp->rbp1->cnt == sp->iface->mtu) {
  123.                 /* Current mbuf is full; link in another */
  124.                 sp->rbp1->next = alloc_mbuf(sp->iface->mtu);
  125.                 sp->rbp1 = sp->rbp1->next;
  126.                 sp->rcp = sp->rbp1->data;
  127.             }
  128.             /* Store the character, increment fragment and total
  129.              * byte counts
  130.              */
  131.             *sp->rcp++ = c;
  132.             sp->rbp1->cnt++;
  133.             sp->rcnt++;
  134.         }
  135.     }
  136. }
  137.